【详解】树莓派开源驱动库BCM2835之SPI |
您所在的位置:网站首页 › bcm2835 gpio › 【详解】树莓派开源驱动库BCM2835之SPI |
{ if (!bcm2835_init)//所有外围io引脚初始化,之前已经分析过了 { printf("bcm2835_init failed. Are you running as root??n"); return 1; } /*spi相关的功能引脚初始化,主要的是将spi对应的io设置成spi功能,将CS寄存器清0,清spi TX和RX的接收发送缓存。 */ if (!bcm2835_spi_begin){ printf("bcm2835_spi_begin failed. Are you running as root??n"); return 1; } bcm2835_spi_begin; bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); //The default /*将SPI的数据通信模式设置为模式BCM2835_SPI_MODE0,即CPOL = 0, CPHA = 0 CPOL = 0通信空闲状态时时钟线为高电平,CPHA = 0第二个时钟边沿采样数据。 */ bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); //The default //时钟分频 bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); //拉低片选引脚 bcm2835_spi_chipSelect(BCM2835_SPI_CS0); bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); //the default char buf[] = { 0x01, 0x02, 0x11, 0x33 };//Data to send bcm2835_spi_transfern(buf, sizeof(buf));//数据发送和接收 //buf will now be filled with the data that was read from the slave printf("Read from SPI: %02X %02X %02X %02X n", buf[0], buf[1], buf[2], buf[3]); bcm2835_spi_end; bcm2835_close; return 0; } bcm2835_spi_transfern是通过调用bcm2835_spi_transfernb来完成数据的发送的。 void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len) { volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; uint32_t TXCnt=0; uint32_t RXCnt=0; /* Clear TX and RX fifos */ bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); /* Set TA = 1,设置TA将SPI恢复到未通信状态 */ bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); /* Use the FIFO's to reduce the interbyte times */ while((TXCnt < len)||(RXCnt < len))//发送和接收循环 { /* TX fifo not full, so add some more bytes */ while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))&&(TXCnt < len )) { bcm2835_peri_write_nb(fifo, tbuf[TXCnt]); TXCnt++; } /* Rx fifo not empty, so get the next received bytes */ while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD))&&( RXCnt < len )) { rbuf[RXCnt] = bcm2835_peri_read_nb(fifo); RXCnt++; } } /* Wait for DONE to be set */ //等待通信结束 while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)); /* Set TA = 0, and also set the barrier */ bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);//设置TA位结束通信 } ←左右滑动,查看全部代码→ 实 例 效 果 下面借助图片来看一下树莓派spin.c回环实验的效果。 上图是用逻辑分析仪抓到的数据,channel 1和channel 2分别是MOSI和MISO,channel 3是时钟信号,时钟模式为CPOL = 0, CPHA = 0。CS片选为channel 4,通信时将其拉低使能SPI。 下图是树莓派3的外围IO图,左红色方框是spi的主要三个引脚,右边CE可不接,做loop是将MOSI和MISO互连,GDN和逻辑分析仪互连(最好相连,否则参考电平不同可能会出现解码错误)。 *本文作者为CSDN博主「KosingZhu」 原文地址为 https://blog.csdn.net/housezhu/article/details/77926641返回搜狐,查看更多 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |